import 'dart:convert';
import 'dart:typed_data';
import 'package:pointycastle/export.dart';

/// AES CBC 工具类，使用 pointycastle 实现
class AESCBCUtil {
  static const String key = "HQTong2023000000";
  static const String iv = "2023070420151215";

  /// 加密：对字符串进行加密，并返回十六进制字符串(hex)
  ///
  /// @param encryptStr 需要加密的字符串
  /// @return 加密后的十六进制字符串(hex)
  static String? encrypt(String? encryptStr) {
    if (encryptStr == null || encryptStr.isEmpty) {
      return "";
    }

    try {
      final keyBytes = Uint8List.fromList(utf8.encode(key));
      final ivBytes = Uint8List.fromList(utf8.encode(iv));

      final cipher = CBCBlockCipher(AESEngine())
        ..init(true, ParametersWithIV(KeyParameter(keyBytes), ivBytes)); // true=encrypt

      // 使用 PKCS7 填充
      final paddedText = _pad(encryptStr);
      final paddedBytes = Uint8List.fromList(utf8.encode(paddedText));

      // 加密
      final encryptedBytes = Uint8List(paddedBytes.length);
      for (int i = 0; i < paddedBytes.length; i += 16) {
        cipher.processBlock(paddedBytes, i, encryptedBytes, i);
      }

      return _bytesToHex(encryptedBytes);
    } catch (ex) {
      print(ex);
      return null;
    }
  }

  /// 解密：对加密后的十六进制字符串(hex)进行解密，并返回字符串
  ///
  /// @param encryptedStr 需要解密的，加密后的十六进制字符串
  /// @return 解密后的字符串
  static String? decrypt(String? encryptedStr) {
    if (encryptedStr == null || encryptedStr.isEmpty) {
      return "";
    }

    try {
      final keyBytes = Uint8List.fromList(utf8.encode(key));
      final ivBytes = Uint8List.fromList(utf8.encode(iv));

      final cipher = CBCBlockCipher(AESEngine())
        ..init(false, ParametersWithIV(KeyParameter(keyBytes), ivBytes)); // false=decrypt

      // 将十六进制字符串转换为字节数组
      final encryptedBytes = _hexToBytes(encryptedStr);

      // 解密
      final decryptedBytes = Uint8List(encryptedBytes.length);
      for (int i = 0; i < encryptedBytes.length; i += 16) {
        cipher.processBlock(encryptedBytes, i, decryptedBytes, i);
      }

      // 去除填充
      final unpaddedBytes = _unpad(decryptedBytes);
      return utf8.decode(unpaddedBytes);
    } catch (ex) {
      print(ex);
      return null;
    }
  }

  /// PKCS7 填充
  static String _pad(String text) {
    final bytes = utf8.encode(text);
    final padLength = 16 - (bytes.length % 16);
    final paddedBytes = Uint8List(bytes.length + padLength);
    paddedBytes.setAll(0, bytes);
    for (int i = bytes.length; i < paddedBytes.length; i++) {
      paddedBytes[i] = padLength;
    }
    return utf8.decode(paddedBytes);
  }

  /// PKCS7 去填充
  static Uint8List _unpad(Uint8List bytes) {
    final padLength = bytes[bytes.length - 1];
    return Uint8List.view(bytes.buffer, 0, bytes.length - padLength);
  }

  /// 十六进制字符串转换为byte[]
  static Uint8List _hexToBytes(String hexStr) {
    hexStr = hexStr.replaceAll(' ', '').toUpperCase();
    final bytes = Uint8List(hexStr.length ~/ 2);

    for (int i = 0; i < hexStr.length; i += 2) {
      bytes[i ~/ 2] = int.parse(hexStr.substring(i, i + 2), radix: 16);
    }

    return bytes;
  }

  /// byte[]转换为十六进制字符串
  static String _bytesToHex(Uint8List bytes) {
    final buffer = StringBuffer();
    for (var byte in bytes) {
      buffer.write('${byte < 16 ? '0' : ''}${byte.toRadixString(16)}');
    }
    return buffer.toString();
  }
}